﻿using System.Diagnostics;
using System.Text;
using Dapper;
using Dapper.Abstractions;

namespace DataAccess.Api.Endpoints.Blog;

public class Insert : IEndpoint
{
    public void MapEndpoint(IEndpointRouteBuilder app)
    {
	    app.MapPost("/api/blogs/dapper-insert", async (IDbConnectionFactory factory) => 
	    {
		    var blogs = DataGenerator.GenerateBlogs(100000);
		    var sw = Stopwatch.StartNew();
    
		    using var conn = await factory.CreateConnectionAsync();
		    // 开启事务
		    using var transaction = conn.BeginTransaction();
    
		    try
		    {
			    const int batchSize = 1000;
			    for (int i = 0; i < blogs.Count; i += batchSize)
			    {
				    var batch = blogs.Skip(i).Take(batchSize);
				    var parameters = new DynamicParameters();
				    var sqlBuilder = new StringBuilder("INSERT INTO blogs (Url) VALUES ");
            
				    int paramIndex = 0;
				    foreach (var blog in batch)
				    {
					    sqlBuilder.Append($"(@u{paramIndex}),");
					    parameters.Add($"u{paramIndex}", blog.Url);
					    parameters.Add($"r{paramIndex}", blog.Rating);
					    paramIndex++;
				    }
				    sqlBuilder.Length--; // 移除末尾逗号
            
				    // 在事务中执行
				    await conn.ExecuteAsync(
					    sqlBuilder.ToString(), 
					    parameters,
					    transaction: transaction
				    );
			    }
        
			    // 所有批次成功后提交事务
			    transaction.Commit();
		    }
		    catch
		    {
			    // 出错时回滚事务
			    transaction.Rollback();
			    throw;  // 重新抛出异常
		    }
    
		    sw.Stop();
		    Console.WriteLine($"Elapsed time: {sw.ElapsedMilliseconds} ms");
		    return Results.Ok("100,000 blogs inserted with transaction support.");
	    })
	    .WithName("DapperInsertBlogs")
	    .WithTags(Tags.Blog);
    }
}
